package com.zx._07_数据库.jdbc;

import com.github.javafaker.Faker;
import com.google.common.collect.Lists;
import com.zx.common.entity.UserData;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class 造数据2 {

    private static final int poolSize = 2;

    private static final int capacity = 2000;

    private static final int num = 1000 * 1000;
//	private static int num = 1000 * 1000 * 10;


    public static void main(final String[] args) throws Exception {
        final AtomicInteger counter = new AtomicInteger(0);
        final ExecutorService pool = Executors.newFixedThreadPool(poolSize);
        final LinkedBlockingQueue<UserData> queue = new LinkedBlockingQueue<>();

        final long begin = System.currentTimeMillis();
        final AtomicBoolean isDone = new AtomicBoolean(false);
        pool.execute(() -> {
            final Faker fakerWithCN = new Faker(Locale.CHINA);// Locale.US  美国的数据
            for (int i = 1; i <= num; i++) {
                final UserData userInfo = new UserData();
                userInfo.setId(i * 1L);
                userInfo.setRealName(fakerWithCN.name().fullName());
                userInfo.setCellPhone(fakerWithCN.phoneNumber().cellPhone());
                userInfo.setCity(fakerWithCN.address().city());
                userInfo.setStreet(fakerWithCN.address().streetAddress());
                userInfo.setUniversityName(fakerWithCN.university().name());
                try {
                    queue.put(userInfo);
                } catch (final InterruptedException e) {
                    e.printStackTrace();
                }
            }
            isDone.getAndSet(true);
        });

        for (int i = 0; i < poolSize - 1; i++) {
            pool.execute(() -> {
                final List<UserData> list = Lists.newArrayListWithCapacity(capacity);
                while (!(queue.isEmpty() && isDone.get())) {
                    final UserData poll = queue.poll();
                    if (poll == null) {
                        continue;
                    }
                    list.add(poll);
                    counter.incrementAndGet();
                    if (list.size() == capacity) {
                        save(list);
                        list.clear();
                    }
                }
                if (list.size() > 0) {
                    save(list);
                }
            });
        }
        pool.shutdown();
        while (!pool.awaitTermination(1L, TimeUnit.SECONDS)) {
            log.info("run {}%", (counter.get() * 100 / num));
        }
        log.info("done {}", (System.currentTimeMillis() - begin) / 1000);
    }

    public static void save(final List<UserData> list) {
        final Connection con = JDBC.getConnection();
        final String sql = "INSERT INTO t_member(id, real_name, cell_phone, university_name, city, street) VALUES(?, ?, ?, ?, ?, ?)";
        PreparedStatement ps = null;
        try {
            ps = con.prepareStatement(sql);
            for (final UserData user : list) {
                ps.setLong(1, user.getId());
                ps.setString(2, user.getRealName());
                ps.setString(3, user.getCellPhone());
                ps.setString(4, user.getUniversityName());
                ps.setString(5, user.getCity());
                ps.setString(6, user.getStreet());
                ps.addBatch();
            }
            ps.executeBatch();//执行批！
        } catch (final SQLException e) {
            e.printStackTrace();
        } finally {
            JDBC.release(con, ps, null);
        }
    }

}
